// Copyright (c) 2006 by M. David Peterson
// The code contained in this file is licensed under The MIT License
// Please see http://www.opensource.org/licenses/mit-license.php for specific detail.

using System;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Web;
using System.Xml;
using System.Xml.XPath;
using System.Xml.Xsl;
using Saxon.Api;
using Xameleon.Function;

namespace Nuxleus.Web.HttpHandler
{

    public struct NuxleusHttpAsyncAtomicXmlPageHandler : IHttpAsyncHandler
    {
        TextWriter m_writer;
        Nuxleus.Agent.NuxleusAsyncResult m_nuxleusAsyncResult;
        String m_httpMethod;
        Exception m_exception;
        string m_lastModifiedDate;
        static Stopwatch m_stopwatch = new Stopwatch();
        StringBuilder m_builder;


        public void ProcessRequest(HttpContext context)
        {
            //not called
        }

        public bool IsReusable
        {
            get { return false; }
        }

        #region IHttpAsyncHandler Members

        public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData)
        {

            m_stopwatch.Start();
            m_builder = new StringBuilder();
            m_nuxleusAsyncResult = new Nuxleus.Agent.NuxleusAsyncResult(cb, extraData);


            context.Response.ContentType = "text/xml";
            // Create a Processor instance.
            Processor processor = new Processor();

            Uri baseDocument = new Uri(context.Request.MapPath("~/index.page"));
            Uri baseUri = new Uri(context.Request.MapPath("~/service/transform/controller/atomictalk/base.xslt"));

            // Load the source document
            XdmNode input = processor.NewDocumentBuilder().Build(baseDocument);

            // Create a transformer for the stylesheet.
            XsltCompiler compiler = processor.NewXsltCompiler();
            compiler.BaseUri = baseDocument;


            // Create a serializer, with output to the standard output stream
            Serializer serializer = new Serializer();
            serializer.SetOutputWriter(context.Response.Output);


            XsltTransformer transformer = compiler.Compile(baseUri).Load();
            transformer.SetParameter(new QName("", "", "current-context"), new XdmValue((XdmItem)XdmAtomicValue.wrapExternalObject(context)));
            //FunctionWrapper wrapper = new FunctionWrapper();
            //transformer.SetParameter(new QName("", "", "XameleonFunctions"), new XdmValue((XdmItem)XdmAtomicValue.wrapExternalObject(wrapper)));

            // Set the root node of the source document to be the initial context node
            transformer.InitialContextNode = input;


            // Transform the source XML and serialize the result document
            transformer.Run(serializer);
            






            //XslCompiledTransform xslt = new XslCompiledTransform();
            //xslt.Load(context.Request.MapPath("~/prices.xsl"));

            //// Load the XML data file.
            //XPathDocument doc = new XPathDocument(context.Request.MapPath("~/books.xml"));

            //// Create an XsltArgumentList.
            //XsltArgumentList xslArg = new XsltArgumentList();

            //// Add an object to calculate the new book price.
            //BookPrice obj = new BookPrice();
            //xslArg.AddExtensionObject("urn:price-conv", obj);

            //// Transform the file.
            //xslt.Transform(doc, xslArg, context.Response.Output);


            //m_writer = new StringWriter(m_builder);

            m_nuxleusAsyncResult.CompleteCall();
            return m_nuxleusAsyncResult;
        }

        public void EndProcessRequest(IAsyncResult result)
        {
            m_stopwatch.Stop();
            //this.LogDebug("Total processing time: {0} ms", m_stopwatch.ElapsedMilliseconds);
            m_stopwatch.Reset();
        }

        private void WriteError()
        {

        }

        // Convert the book price to a new price using the conversion factor.
        public class BookPrice
        {

            private decimal newprice = 0;

            public decimal NewPriceFunc(decimal price, decimal conv)
            {
                decimal tmp = price * conv;
                newprice = decimal.Round(tmp, 2);
                return newprice;
            }
        }

        #endregion
    }
}